package snowforce;

import java.util.ArrayList;
import java.util.List;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.MediaType;

import snowforce.datatype.EvaluationJSON;
import snowforce.datatype.PassPoint;
import snowforce.storage.GraphStore;
import snowforce.storage.MapHandlerStore;
import snowforce.storage.PassPointStore;

@Path("/evaluation")
public class EvaluationService
{
	@GET
	@Produces(MediaType.APPLICATION_JSON)
	public EvaluationJSON getEvaluationJSON(@QueryParam("level") String levelStr, @QueryParam("timestamp") String timestampStr, @QueryParam("route") String routesStr)
	{
		EvaluationJSON ret = new EvaluationJSON();
		// ret = getDefault();
		int level;
		long timestamp;
		try {
			level = Integer.parseInt(levelStr);
		}
		catch (Exception e) {
			e.printStackTrace();
			ret.setStatus("PARAM_LEVEL_WRONG");
			return ret;
		}
		try {
			timestamp = Long.parseLong(timestampStr);
		}
		catch (Exception e) {
			e.printStackTrace();
			ret.setStatus("PARAM_TIMESTAMP_WRONG");
			return ret;
		}

		// loadPassPointFile("" + level);
		// loadMapFile("" + level);
		// int nextPassPointIndex = caculateNextPassPoint(routesStr, level);
		// mh.ConstructMap(gs.get("" + level), pps.get("" + level));
		// MapHandler mh = new MapHandler();
		// mh.ConstructMap(GraphStore.getStore().get("" + level), PassPointStore.getStore().get("" + level));
		MapHandler mh = MapHandlerStore.getStore().get(""+level);
		List<Integer> passedPointArray = caculatePointArray(routesStr);
		EvaluationResult e = mh.EvaluateRouteResult(passedPointArray, timestamp);
		switch (e) {
			case evaluationInvalidRoute:
				ret.setStatus(EvaluationJSON.EVAL_STATUS_INVALID_ROUTE);
				break;
			case evaluationOk:
				ret.setStatus(EvaluationJSON.EVAL_STATUS_OK);
				break;
			case evaluationTimeOut:
				ret.setStatus(EvaluationJSON.EVAL_STATUS_TIME_OUT);
				break;
		}
		return ret;
	}

	private List<Integer> caculatePointArray(String routesStr)
	{

		List<Integer> a = new ArrayList<Integer>();
		String[] s = routesStr.split("\\|");
		if (s.length == 1) {
			a.add(Integer.parseInt(s[0].substring(0, 2)));
			a.add(Integer.parseInt(s[0].substring(2, 4)));
			return a;
		}
		for (int i = 0; i < s.length; i++) {
			String edgeId = s[i];
			String pointId1 = edgeId.substring(0, 2);
			String pointId2 = edgeId.substring(2, 4);
			if (i == 0) {
				if (s[i + 1].indexOf(pointId1) != -1) {
					a.add(Integer.parseInt(pointId2));
					a.add(Integer.parseInt(pointId1));
				}
				else {
					a.add(Integer.parseInt(pointId1));
					a.add(Integer.parseInt(pointId2));
				}
			}
			else {
				if (s[i - 1].indexOf(pointId1) != -1) {
					a.add(Integer.parseInt(pointId2));
				}
				else {
					a.add(Integer.parseInt(pointId1));
				}
			}
		}
		return a;
	}

	private int caculateNextPassPoint(String routesStr, int level)
	{
		List<PassPoint> p = PassPointStore.getStore().get("" + level);
		String[] s = routesStr.split("\\|");
		int index = 0;
		for (int i = 0; i < s.length; i++) {
			String edgeId = s[i];
			String pointId = p.get(index).getPoint() + "";
			if (pointId.length() < 2) {
				pointId = "0" + pointId;
			}
			if ((edgeId.indexOf(pointId) == 0 || edgeId.indexOf(pointId) == 2)) {
				index++;
			}
		}
		return index;
	}

	private EvaluationJSON getDefault()
	{
		EvaluationJSON e = new EvaluationJSON();

		e.setStatus(EvaluationJSON.EVAL_STATUS_OK);
		e.setEval(0.0f);
		System.out.println(e);
		return e;
	}

}